package cn.iocoder.yudao.module.promotion.groupon.service.app;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.business.order.service.AppOrderBaseService;
import cn.iocoder.yudao.framework.common.exception.Assertions;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.api.pay.bill.enums.BillTypeEnum;
import cn.iocoder.yudao.module.api.pay.order.PayOrderApi;
import cn.iocoder.yudao.module.api.pay.order.dto.PayOrderCreateDTO;
import cn.iocoder.yudao.module.api.pay.order.vo.PayOrderVO;
import cn.iocoder.yudao.module.api.promotion.groupon.dto.GrouponPackageRespDTO;
import cn.iocoder.yudao.module.promotion.gift.service.core.CoreGiftRecordService;
import cn.iocoder.yudao.module.promotion.groupon.dao.GrouponOrderMapper;
import cn.iocoder.yudao.module.promotion.groupon.dao.GrouponPackageMapper;
import cn.iocoder.yudao.module.promotion.groupon.pojo.dto.GrouponOrderSubmitDTO;
import cn.iocoder.yudao.module.promotion.groupon.pojo.po.GrouponOrder;
import cn.iocoder.yudao.module.promotion.groupon.pojo.po.GrouponPackage;
import cn.iocoder.yudao.module.promotion.groupon.pojo.vo.GrouponOrderVO;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.HashSet;

//import static cn.iocoder.yudao.module.api.promotion.ConfigConstants.GROUPON_PACKAGE_ORDER_NO_PREFIX;

/**
 * <pre>
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * 服务
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * </pre>
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2025/05/14
 */
@Service
public class AppGrouponOrderService extends AppOrderBaseService<GrouponOrder, GrouponOrderVO, GrouponOrderSubmitDTO> {
    @Resource
    private GrouponOrderMapper grouponOrderMapper;
    @Resource
    private GrouponPackageMapper grouponPackageMapper;

    @Resource
    @Lazy // TODO 延迟加载，避免循环依赖
    private CoreGiftRecordService coreGiftRecordService;

//    @Resource
//    private SerialNoRedisRepository serialNoRedisRepository;

    @Resource
    private PayOrderApi payOrderApi;

    @Override
    public GrouponOrderMapper getInjectedMapper() {
        return grouponOrderMapper;
    }

    @Nonnull
    @Override
    protected GrouponOrder onOrderCreateBefore(@Nonnull GrouponOrderSubmitDTO dto, @Nonnull Long userId) {
        GrouponPackage entity = grouponPackageMapper.selectById(dto.getPackageId());
        Assertions.notNull(entity, "团购套餐获取失败，无法创建团购订单");
        // 构建订单信息
        GrouponOrder order = new GrouponOrder();
        order.setUserId(userId);
        order.setShopId(entity.getShopId());
        order.setPackageId(entity.getId());
        order.setType(entity.getType());
        order.setPrice(entity.getPrice());
        order.setSnapshot(JSONUtil.toJsonStr(BeanUtils.toBean(entity, GrouponPackageRespDTO.class)));
        /*order.setTradeNo(serialNoRedisRepository.generateNo(GROUPON_PACKAGE_ORDER_NO_PREFIX));*/
        order.setTradeNo(dto.getTradeNo());
        order.setPayNo(dto.getPayNo());
        order.setGiftActivityIds(entity.getGiftActivityIds());
        order.setNote("购买团购套餐【%s】".formatted(entity.getName()));
        return order;
    }

    @Async
    @Override
    public void createPayOrder(@Nonnull GrouponOrder order) {
        PayOrderVO orderVO = payOrderApi.getOrderByTradeNo(order.getTradeNo());
        if (orderVO != null) {
            // 已经通过杂糅的交易订单创建了付款单，此处忽略
            return;
        }
        PayOrderCreateDTO createDTO = new PayOrderCreateDTO();
        createDTO.setTradeNo(order.getTradeNo());
        createDTO.setSubject(BillTypeEnum.PAY_GROUPON_PACKAGE.getName());
        createDTO.setBody(order.getNote());
        createDTO.setPrice(order.getPrice());
        String payNo = payOrderApi.createOrder(createDTO);
        // 创建付款单据后再回来更新业务订单的支付单号
        GrouponOrder updateObj = new GrouponOrder();
        updateObj.setId(order.getId());
        updateObj.setPayNo(payNo);
        getInjectedMapper().updateById(updateObj);
    }

    @Override
    protected void onPaidAfter(GrouponOrder order) {
        if (CollUtil.isEmpty(order.getGiftActivityIds())) {
            return;
        }
        coreGiftRecordService.pending(order.getUserId(), order.getTradeNo(), new HashSet<>(order.getGiftActivityIds()));
    }

}
